package com.cn.controller;

import cn.hutool.core.util.BooleanUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSON;
import com.cn.constant.CacheConstant;
import com.cn.mapper.ShopMapper;
import com.cn.pojo.TbShop;
import com.cn.pojo.User;
import com.cn.response.BaseResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.constraints.NotNull;
import java.util.concurrent.TimeUnit;

/**
 * 测试redis
 */
@RestController
@RequestMapping("redis")
@Slf4j
@Validated
public class RedisContrller {

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private ShopMapper shopMapper;

    @GetMapping("/testShopMapper")
    public Object testShopMapper(){
        TbShop byId = shopMapper.getById(1l);
        return byId;
    }
    /**
     * 判断参数是否为方式
     * @param id
     * @return
     * @throws Exception
     */
    @GetMapping("/test")
    public Object test(@NotNull(message = "参数不为空") Integer id) throws Exception {
        log.info("成","s");
        System.out.println(id);
        return "错误";
    }

    /**
     * 参数校验方式
     * @param user
     * @return
     */
    @PostMapping("/testValidation")
    public Object testValidation(@Validated User user){
        log.info("成","s");
        System.out.println(user);
        return "成功";
    }

    @GetMapping("/getById")
    public Object getById(@NotNull(message = "参数不为空") Integer id){
        //查询缓存
        //查询数据
        User user = new User();
        user.setEmail("13");
        user.setUsername("set");
        user.setPassword("sdf");
        //添加缓存
        stringRedisTemplate.opsForValue().set(CacheConstant.shopConstant+id, JSON.toJSONString(user),30l,TimeUnit.SECONDS);
        //返回
        return "成功";
    }

    public boolean tryLock(){
        long id = Thread.currentThread().getId();
        Boolean isFlag = stringRedisTemplate.opsForValue().setIfAbsent(id+"", "1", 10, TimeUnit.SECONDS);
        return BooleanUtil.isTrue(isFlag);
    }

    public void unLock(String id){
        String idThread = Thread.currentThread().getId()+"";
        String cacheThread = stringRedisTemplate.opsForValue().get(id);
        if (idThread.equals(cacheThread)) {
            stringRedisTemplate.delete(id);
        }
    }

    /**
     * 开始缓存重构的方式
     * @return
     */
    @GetMapping("/queryWithMutex")
    public BaseResponse<Object> queryWithMutex(Long id){
        //1.查询缓存
        String key = CacheConstant.codeConstant + id;
        String cacheShop = stringRedisTemplate.opsForValue().get(key);
        if (StrUtil.isNotBlank(cacheShop)){
            return BaseResponse.success(cacheShop);
        }
        try {
            boolean isFlag = tryLock();
            if (!isFlag){
                Thread.sleep(100);
                queryWithMutex(id);
            }
            //2.查询数据库
            log.info("获取到数据");
            //3.添加缓存中
            stringRedisTemplate.opsForValue().set(key,JSON.toJSONString(new User()),10L,TimeUnit.SECONDS);
        }catch (Exception e){

        }finally {
            unLock(key);
        }
        return BaseResponse.success("成功");
    }
}
